Namespace definitions

Global namespace containing types and functions accessible without any namespace prefix.

Global namespace containing types and functions accessible without any namespace prefix.

Types

Link copied to clipboard

An immutable signed integer type, supporting extremely large values (upwards of 100,000 decimal digits).

Literals of big_integer type can be written like integers, but with the suffix L, e.g. 123L or 0x123L. big_integers support the operators +, -, *, / and % with typical behavior.

Link copied to clipboard
type boolean

A simple data type that represents two values: true and false.

Link copied to clipboard

An array of bytes. This type is immutable.

Link copied to clipboard
hidden abstract type collection<T> : iterable<T>

A generic type for mutable ordered collections of elements. Subtype of iterable<T>. Supports many standard operations such add insertion, removal, lookup and sorting.

Link copied to clipboard
hidden abstract type comparable
Link copied to clipboard
type decimal

A real number data type with high precision.

Not a complete equivalent of floating-point types, as there are a fixed maximum number of digits before the decimal point (131072, or 2^17 digits) and after the decimal point (20 digits).

Examples:

  • 123.456

  • .789

  • 7e+33

  • decimal('123456789.98765')

Link copied to clipboard
hidden abstract type entity

Common parent type of all entity types. An entity is a data structure that reside in the SQL database.

Link copied to clipboard
hidden abstract type enum

An enum is a set of member constants who share a type.

The declaration enum example { A, B, C } defines a type example, with three member constants, example.A, example.B and example.C.

Enum names and member constant names follow the same rules as all identifiers in Rell. However, by convention, enum names use snake_case, and member constants use UPPER_SNAKE_CASE.

Examples:

  • enum primary_color { RED, BLUE, GREEN }

  • enum error { TIMEOUT, MALFORMED_RESPONSE, NOT_FOUND, UNAUTHORIZED, UNKNOWN }

  • enum cardinal_direction { NORTH, EAST, SOUTH, WEST }

Link copied to clipboard
type gtv

Generic Transfer Value (GTV) is a data type for the serialization and transfer of structured data, much like JSON.

GTV is used in Rell to encode operation and query arguments and results that are exchanged with clients. Unlike JSON, GTV has a stable byte serialization format and well-defined cryptographic hash, making it well-suited to this purpose. In addition, GTV supports byte arrays.

GTV supports the following types:

GTV TypeClosest Rell Equivalent
NULLnull
BYTEARRAYbyte_array
STRINGtext
INTEGERinteger
DICTmap<text, gtv>
ARRAYlist<gtv>
BIGINTEGERbig_integer

GTV does not support all Rell types, so not every value in Rell can be converted to GTV. For example, GTV has no support for non-integer numbers, and therefore the decimal type is encoded in GTV as text.

Rell types can be encoded as GTV in two modes: compact and pretty, and the distinction between the two is a real semantic difference, and is not merely a difference in whitespace when converted to text. The two modes differ in the following ways:

  • Compact GTV encode struct values as a lists of attributes, while pretty GTV encode them as a dictionaries (thus struct member names are preserved).

  • Compact GTV encode named-field tuples as a lists of attributes, while pretty GTV encode them as a dictionaries (thus tuple field names are preserved). There is no difference between the two in encoding of unnamed-field tuples.

Examples of GTV:

>>> (x = 1, y = 'a', z = true).to_gtv()
[1,"a",1]
>>> (x = 1, y = 'a', z = false).to_gtv_pretty()
{"x":1,"y":"a","z":0}
>>> [1: 'a', 2: 'b', 3: 'c'].to_gtv()
[[1,"a"],[2,"b"],[3,"c"]]
>>> [1: 'a', 2: 'b', 3: 'c'].to_gtv_pretty()
[[1,"a"],[2,"b"],[3,"c"]]
>>> set([1, 2, 3, 4]).to_gtv()
[1,2,3,4]
>>> set([1, 2, 3, 4]).to_gtv_pretty()
[1,2,3,4]
>>> struct a { x: integer; y: decimal; };
>>> a(10, 10.1).to_gtv()
[10,"10.1"]
>>> a(10, 10.1).to_gtv_pretty()
{"x":10,"y":"10.1"}

Rell operations expect their arguments as compact-encoded GTV, whereas queries expect pretty-encoded GTV arguments, hence client applications are required to use those respective formats when making operation and query calls to Rell applications.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
alias GTXValue = gtv

Generic Transfer Value (GTV) is a data type for the serialization and transfer of structured data, much like JSON.

GTV is used in Rell to encode operation and query arguments and results that are exchanged with clients. Unlike JSON, GTV has a stable byte serialization format and well-defined cryptographic hash, making it well-suited to this purpose. In addition, GTV supports byte arrays.

GTV supports the following types:

GTV TypeClosest Rell Equivalent
NULLnull
BYTEARRAYbyte_array
STRINGtext
INTEGERinteger
DICTmap<text, gtv>
ARRAYlist<gtv>
BIGINTEGERbig_integer

GTV does not support all Rell types, so not every value in Rell can be converted to GTV. For example, GTV has no support for non-integer numbers, and therefore the decimal type is encoded in GTV as text.

Rell types can be encoded as GTV in two modes: compact and pretty, and the distinction between the two is a real semantic difference, and is not merely a difference in whitespace when converted to text. The two modes differ in the following ways:

  • Compact GTV encode struct values as a lists of attributes, while pretty GTV encode them as a dictionaries (thus struct member names are preserved).

  • Compact GTV encode named-field tuples as a lists of attributes, while pretty GTV encode them as a dictionaries (thus tuple field names are preserved). There is no difference between the two in encoding of unnamed-field tuples.

Examples of GTV:

>>> (x = 1, y = 'a', z = true).to_gtv()
[1,"a",1]
>>> (x = 1, y = 'a', z = false).to_gtv_pretty()
{"x":1,"y":"a","z":0}
>>> [1: 'a', 2: 'b', 3: 'c'].to_gtv()
[[1,"a"],[2,"b"],[3,"c"]]
>>> [1: 'a', 2: 'b', 3: 'c'].to_gtv_pretty()
[[1,"a"],[2,"b"],[3,"c"]]
>>> set([1, 2, 3, 4]).to_gtv()
[1,2,3,4]
>>> set([1, 2, 3, 4]).to_gtv_pretty()
[1,2,3,4]
>>> struct a { x: integer; y: decimal; };
>>> a(10, 10.1).to_gtv()
[10,"10.1"]
>>> a(10, 10.1).to_gtv_pretty()
{"x":10,"y":"10.1"}

Rell operations expect their arguments as compact-encoded GTV, whereas queries expect pretty-encoded GTV arguments, hence client applications are required to use those respective formats when making operation and query calls to Rell applications.

Alias
Link copied to clipboard
hidden abstract type immutable
Link copied to clipboard
hidden abstract type immutable_mirror_struct<T> : mirror_struct<T>
Link copied to clipboard
type integer

A 64-bit signed integer type, ranging from -2^63 to (2^63)-1, supporting a standard complement of numerical operations.

Link copied to clipboard
hidden abstract type iterable<T>

A generic type for sequences that can be iterated over, such as collections, ranges and maps.

Link copied to clipboard
type json

Wrapper object for a JSON-string.

Link copied to clipboard
type list<T> : collection<T>

Represents a mutable array list. Subtype of collection<T>.

Link copied to clipboard
type map<K: -immutable, V> : iterable<(K, V)>

A mutable map from keys of type K to values of type V, where K is immutable, and V may be either mutable or immutable. map<K,V> is a subtype of iterable<(K,V)>`. It is implemented as a hash-map, with iteration order determined by the order in which the entries were added.

Link copied to clipboard
hidden type map_entry<K, V>

A supertype of all two-element tuples (K, V) (with named and unnamed fields), where K is an immutable type, and V may be either mutable or immutable. Generally used for iterating over maps and constructing maps from iterables.

Link copied to clipboard
hidden abstract type mirror_struct<T>
Link copied to clipboard
hidden abstract type mutable_mirror_struct<T> : mirror_struct<T>
Link copied to clipboard
alias name = text

An immutable character string data type.

Alias
Link copied to clipboard
hidden abstract type null_ext
Link copied to clipboard
hidden abstract type object
Link copied to clipboard
hidden abstract type operation
Link copied to clipboard

An array of bytes. This type is immutable.

Link copied to clipboard

A range of integer values. Ranges represent arithmetic sequences with defined start and end points, and a constant difference between consecutive elements. Ranges can be empty or contain any natural number of elements.

Range is a subtype of iterable<integer>.

Link copied to clipboard
type rowid

The primary key of a database record, a 64-bit integer.

Link copied to clipboard
type set<T: -immutable> : collection<T>

A mutable set of elements of type T, where T is immutable. Subtype of collection<T>. Implemented as a hash-set, with iteration order determined by the order in which the elements were added.

Link copied to clipboard
hidden abstract type struct
Link copied to clipboard
type text

An immutable character string data type.

Link copied to clipboard

A 64-bit signed integer type, ranging from -2^63 to (2^63)-1, supporting a standard complement of numerical operations.

Alias
Link copied to clipboard
type unit
Link copied to clipboard
hidden type virtual<T>
Link copied to clipboard
hidden abstract type virtual_collection<T> : iterable<T>
Link copied to clipboard
hidden type virtual_list<T, T2> : virtual_collection<T2>
Link copied to clipboard
hidden type virtual_map<K: -immutable, V0, V> : iterable<(K, V)>
Link copied to clipboard

Functions

Link copied to clipboard

Returns the absolute value of a big_integer value; i.e. the value itself if it's positive or its negation if it's negative.

function abs(a: decimal): decimal

Returns the absolute value of a decimal value; i.e. the value itself if it's positive or its negation if it's negative.

function abs(a: integer): integer

Returns the absolute value of a integer value; i.e. the value itself if it's positive or its negation if it's negative.

Link copied to clipboard
(alias) function <T> assert_equals(actual: T, expected: T)

Asserts that two values are equal.

Link copied to clipboard
(alias) function assert_events(expected: (text, gtv)...)

Asserts that the expected events has been emitted during last block

Link copied to clipboard
(alias) function <T> assert_fails(fn: () -> T): rell.test.failure

Asserts that a function fails to evaluate

(alias) function <T> assert_fails(expected_message: text, fn: () -> T): rell.test.failure

Asserts that a function fails with an expected message

Link copied to clipboard
(alias) function assert_false(actual: boolean)

Asserts that the value is false.

Link copied to clipboard
(alias) function <T: -comparable> assert_ge(actual: T, expected: T)

Asserts that the value is greater than or equal to the expected value

Link copied to clipboard
(alias) function <T: -comparable> assert_ge_le(actual: T, expected1: T, expected2: T)

Asserts that the value is greater than or equal to the first value and less than or equal to the second value.

Link copied to clipboard
(alias) function <T: -comparable> assert_ge_lt(actual: T, expected1: T, expected2: T)

Asserts that the value is greater than or equal to the first value and less than the second value.

Link copied to clipboard
(alias) function <T: -comparable> assert_gt(actual: T, expected: T)

Asserts that the value is greater than the expected value

Link copied to clipboard
(alias) function <T: -comparable> assert_gt_le(actual: T, expected1: T, expected2: T)

Asserts that the value is greater than the first value and less than or equal to the second value.

Link copied to clipboard
(alias) function <T: -comparable> assert_gt_lt(actual: T, expected1: T, expected2: T)

Asserts that the value is greater than the first value and less than the second value.

Link copied to clipboard
(alias) function <T: -comparable> assert_le(actual: T, expected: T)

Asserts that the value is less than or equal to the expected value

Link copied to clipboard
(alias) function <T: -comparable> assert_lt(actual: T, expected: T)

Asserts that the value is less than the expected value

Link copied to clipboard
(alias) function <T> assert_not_equals(actual: T, illegal: T)

Asserts that two values are not equal.

Link copied to clipboard
(alias) function <T: -any> assert_not_null(actual: T?)

Asserts that the value is not null.

Link copied to clipboard
(alias) function assert_null(actual: anything)

Asserts that the value is null.

Link copied to clipboard
(alias) function assert_true(actual: boolean)

Asserts that the value is true.

Link copied to clipboard
function <T> empty(arg: T?): boolean

Checks if a value is null or empty. Equivalent to not exists(...).

Link copied to clipboard
(alias) function eth_ecrecover(r: byte_array, s: byte_array, rec_id: integer, data_hash: byte_array): byte_array

Compute an Ethererum public key from a signature and a hash.

Similar to Solidity's ecrecover(), though differs in that:

  • This function takes rec_id, rather than v, where rec_id == v - 27.

  • The parameter order is different.

  • This function returns a 64-byte public key, not a 20-byte address. An address can be obtained by taking the last 20 bytes of the keccak256() digest of the returned public key, e.g.:

 val address: byte_array = keccak256(eth_ecrecover(...)).sub(44);

The signature (consisting of the r, s and rec_id components) will typically be obtained with a procedure equivalent to eth_sign(data_hash, privkey), where privkey and pubkey form a keypair (pubkey being returned form this method).

The signature component rec_id is an adjusted recovery identifier, equivalent to Ethereum's recovery identifier (usually denoted as v) minus 27, i.e. rec_id == v - 27.

The given 32-byte array data_hash is typically a cryptographic hash obtained from a larger data structure using a hashing function such as hash(), sha256() or keccak256().

Example

The following is a Node.js script which uses ecrecover() (the equivalent to crypto.eth_ecrecover()) from the Ethereum Web3 library:

const Web3 = require('web3');
const web3 = new Web3();

var r = '0xcf722a47bcf1da61967ccc6405e31db4d37bce153255a6937e5cceb222caead0';
var s = '0xcf722a47bcf1da61967ccc6405e31db4d37bce153255a6937e5cceb222caead0';
var h = '0x53d7b11e61a8059aa4bc3248d24b2936436c9796dfe7f18e414c181004f79427';
var v = '0x1c';

var address = web3.eth.accounts.recover({'r':r,'s':s,'messageHash':h,'v':v});
console.log(address); // prints 0x5b0c087542D5C1E66Df0041e179c4201675B1614

An equivalent script in Rell is as follows:

val r = x'cf722a47bcf1da61967ccc6405e31db4d37bce153255a6937e5cceb222caead0';
val s = x'cf722a47bcf1da61967ccc6405e31db4d37bce153255a6937e5cceb222caead0';
val h = x'53d7b11e61a8059aa4bc3248d24b2936436c9796dfe7f18e414c181004f79427';
val v = 0x1c;

val pubkey = eth_ecrecover(r, s, v - 27, h);
val address = keccak256(pubkey).sub(12);
print(address); // prints 0x5b0c087542d5c1e66df0041e179c4201675b1614

Note that in the Rell script, v is an integer, while in the Node.js script it is an 0x-prefixed hexadecimal string.

Link copied to clipboard
function <T> exists(arg: T?): boolean

Checks if a value is not null or empty.

An argument can be:

  1. Nullable type (T?) - checked for null.

  2. Collection (list, set, map) - checked for being empty (a nullable collection is also checked for null).

Special case: when used within a database at-expression, and the argument is also a database at-expression, it becomes a nested at-expression, which can use entities of the outer one. The call is translated into the SQL EXISTS clause with a nested SELECT.

Link copied to clipboard
function is_signer(pubkey: byte_array): boolean

Check if a given public key is a signer of the current transaction; i.e. if it's in the list of signers returned by op_context.get_signers().

Link copied to clipboard
(alias) function keccak256(input: byte_array): byte_array

Compute the Keccak256 digest (hash) of the given byte array.

Link copied to clipboard
function log(values: anything...)

Prints the given value(s) to the log, with a timestamp, and then terminates the line. When multiple values are provided, each is separated by a single space character.

Link copied to clipboard

Returns the greater of two big_integer values; i.e. a if a > b, or b otherwise.

function max(a: decimal, b: decimal): decimal

Returns the greater of two decimal values; i.e. a if a > b, or b otherwise.

function max(a: integer, b: integer): integer

Returns the greater of two integer values; i.e. a if a > b, or b otherwise.

Link copied to clipboard

Returns the lesser of two big_integer values; i.e. a if a < b, or b otherwise.

function min(a: decimal, b: decimal): decimal

Returns the lesser of two decimal values; i.e. a if a < b, or b otherwise.

function min(a: integer, b: integer): integer

Returns the lesser of two integer values; i.e. a if a < b, or b otherwise.

Link copied to clipboard
function print(values: anything...)

Prints the given value(s) to STDOUT, and then terminates the line. When multiple values are provided, each is separated by a single space character.

Link copied to clipboard
function <T: -any> require(value: T?, message: text): T

Asserts that a value is not null.

function require(value: boolean, message: text)

Asserts a boolean condition.

Link copied to clipboard
function <T: -any> require_not_empty(value: T?, message: text): T

Asserts that a value is non-null.

function <T> require_not_empty(value: list<T>?, message: text): list<T>

Asserts that a list is non-null and non-empty.

function <K: -immutable, V> require_not_empty(value: map<K, V>?, message: text): map<K, V>

Asserts that a map is non-null and non-empty.

function <T: -immutable> require_not_empty(value: set<T>?, message: text): set<T>

Asserts that a set is non-null and non-empty.

Link copied to clipboard
(alias) function <T: -any> requireNotEmpty(value: T?, message: text): T

Asserts that a value is non-null.

(alias) function <T> requireNotEmpty(value: list<T>?, message: text): list<T>

Asserts that a list is non-null and non-empty.

(alias) function <K: -immutable, V> requireNotEmpty(value: map<K, V>?, message: text): map<K, V>

Asserts that a map is non-null and non-empty.

(alias) function <T: -immutable> requireNotEmpty(value: set<T>?, message: text): set<T>

Asserts that a set is non-null and non-empty.

Link copied to clipboard
(alias) function sha256(input: byte_array): byte_array

Compute the SHA-256 digest (hash) of the given byte array.

Link copied to clipboard
function <T> try_call(fn: () -> T): T?

Calls a function and handles exceptions gracefully, returning null if an exception occurs.

function try_call(fn: () -> unit): boolean

Calls a function that doesn't return a value and handles exceptions gracefully.

function <T> try_call(fn: () -> T, default: T): T

Calls a function and handles exceptions gracefully, providing a fallback value if an exception occurs.

Link copied to clipboard
(alias) function verify_signature(data_hash: byte_array, pubkey: byte_array, signature: byte_array): boolean

Verify a signature against a message and public key.

More precisely, verify that signature was obtained with a procedure equivalent to get_signature(data_hash, privkey), where privkey and pubkey form a keypair.

Accepts valid public keys of size 33 or 65 bytes. Note that not all byte arrays of acceptable length constitute valid public keys.